In the following discussion, 'ptr' means either a pointer or a reference.
When you have a ptr to an object, there are two distinct types in question: the static type of the ptr, and the dynamic type of the pointed-to object (the object may actually be of a class that is derived from the class of the ptr).
The 'legality' of the call is checked based on the static type of the ptr, which gives us static type safety (if the type of the ptr can handle the member fn, certainly the pointed-to object can handle it as well, since the pointed-to object is of a class that is derived from the ptr's class).
Suppose ptr's type is 'List' and the pointed-to object's type is 'FastList'. Suppose the fn 'len()' is provided in 'List' and overridden in 'FastList'. The question is: which function should actually be invoked: the function attached to the pointer's type ('List::len()') or the function attached to the object itself ('FastList::len()')?
If 'len()' is a virtual function, as it would be in the above case, the fn attached to the object is invoked. This is called 'dynamic binding', since the actual code being called is determined dynamically (at run time).
On the other hand, if 'len()' were non-virtual, the dispatch would be resolved statically to the fn attached to the ptr's class.